home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / DJ111M2.ZIP / go32 / exphdlr.c < prev    next >
C/C++ Source or Header  |  1994-01-08  |  36KB  |  1,316 lines

  1. /* This is file EXPHDLR.C */
  2. /*
  3. ** Copyright (C) 1993 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
  16. /* Modified for DPMI Implement by H.Tsubakimoto */
  17. /* Merged DPMI with V1.09+ C. Sandmann sandmann@clio.rice.edu */
  18. /* History:66,55 */
  19.  
  20. #include <process.h>
  21. #include <stdio.h>
  22. #include <dos.h>
  23. #include <sys/stat.h>
  24. #include <time.h>
  25. #include <errno.h>
  26. #include <fcntl.h>
  27. #include <string.h>
  28. #include <dir.h>
  29. #include <ctype.h>
  30. #include <io.h>
  31.  
  32. #include "gotypes.h"
  33. #include "gdt.h"
  34. #include "idt.h"
  35. #include "tss.h"
  36. #include "utils.h"
  37. #include "paging.h"
  38. #include "npx.h"
  39. #include "mono.h"
  40. #include "vcpi.h"
  41. #include "graphics.h"
  42. #include "dpmi.h"
  43. #include "extdebug.h"
  44. #include "vcpi.h"
  45. #include "ustat.h"
  46. #include "dpmisim.h"
  47. #include "dalloc.h"
  48. #include "valloc.h"
  49. #include "control.h"
  50.  
  51. extern void do_faulting_finish_message(int);
  52.  
  53. void segfault(word32 v)
  54. {
  55.   if (!using_external_debugger || (tss_ptr == &ed_tss))
  56.   {
  57.     fprintf(stderr, "Segmentation violation in pointer 0x%08lx at %x:%lx\n", v-ARENA, tss_ptr->tss_cs, tss_ptr->tss_eip);
  58.     do_faulting_finish_message(0);
  59.   }
  60.   tss_ptr->tss_irqn = 14; /* make it a segfault */
  61.   tss_ptr->tss_cr2 = v;
  62. }
  63.  
  64. #define CHECK_SEGFAULT(p) { \
  65.   if (!page_is_valid(p)) \
  66.   { \
  67.     segfault(p); \
  68.     return 1; \
  69.   } \
  70. }
  71.  
  72. extern int debug_mode;
  73.  
  74. extern unsigned int cdecl _openfd[];
  75. extern word32 far *graphics_pt;
  76. extern int ctrl_break_hit;
  77.  
  78. extern int was_user_int;
  79. extern word16 vcpi_installed;           /* VCPI Installed flag */
  80. word16 new_pic;                         /* current IRQ0 Vector */
  81. char transfer_buffer[4096];             /* must be near ptr for small model */
  82. word32 transfer_linear;
  83.  
  84. int in_hardware_interrupt = 0;
  85.  
  86. word8 old_master_lo=0x08;
  87. word8 hard_master_lo=0x08, hard_master_hi=0x0f;
  88. word8 hard_slave_lo=0x70,  hard_slave_hi=0x77;
  89.  
  90. word32 user_dta;
  91. static struct REGPACK r;
  92. static int in_graphics_mode=0;
  93. int ctrl_c_causes_break=1;
  94.  
  95. static int i_10(void), i_21(void), i_31(void), i_33(void), generic_handler(void), i_21_44(void);
  96. static int turbo_assist(void);
  97.  
  98. static word32 flmerge(word32 rf, word32 tf)
  99. {
  100.   return (rf & 0xcff) | (tf & 0xfffff300L);
  101. }
  102.  
  103. void static set_controller(int v)
  104. {
  105. /*  disable();  */
  106.   outportb(0x20, 0x11);
  107.   outportb(0x21, v);
  108.   outportb(0x21, 4);
  109.   outportb(0x21, 1);
  110. /*  enable();  */
  111. }
  112.  
  113. static char cntrls_initted = 0;
  114. extern char vector_78h, vector_79h;
  115.  
  116. int find_empty_pic(void)
  117. {
  118.   static word8 try[] = { 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xf8, 0x68, 0x78 };
  119.   int i, j;
  120.   for (i=0; i<sizeof(try); i++)
  121.   {
  122.     char far * far * vec = (char far * far *)(0L+try[i]*4L);
  123.     for (j=1; j<8; j++)
  124.     {
  125.       if (vec[j] != vec[0])
  126.         goto not_empty;
  127.     }
  128. /*    printf("Empty = %d\n", try[i]); */
  129.     return try[i];
  130.     not_empty:;
  131.   }
  132.   return 0x78;
  133. }
  134.  
  135. extern int  far _ev_kbinter;            /* keyboard interrupt flag */
  136. extern void interrupt (* far _ev_oldkbint)(void);
  137. extern void interrupt _ev_keybdint(void);
  138.  
  139. word32 saved_interrupt_table[256];
  140.  
  141. void init_controllers(void)
  142. {
  143.   if(cntrls_initted) return;
  144.   cntrls_initted = 1;
  145.  
  146.   movedata(0, 0, _DS, FP_OFF(saved_interrupt_table), 256*4);
  147.  
  148.   disable();
  149.  
  150.   if (vcpi_installed)
  151.   {
  152.     old_master_lo = vcpi_get_pic();
  153.     hard_slave_lo = vcpi_get_secpic();
  154. /*    printf("VCPI pics were m=%d s=%d\n", old_master_lo, hard_slave_lo); */
  155.     hard_slave_hi = hard_slave_lo + 7;
  156.   }
  157.   else if(!use_DPMI)
  158.   {
  159.     old_master_lo = 0x08;
  160.     hard_slave_lo = 0x70;
  161.     hard_slave_hi = 0x77;
  162.   }
  163.  
  164.   _ev_kbinter = 1;
  165.   _ev_oldkbint = getvect(8+1);     /* this is *NOT* old_master_lo - required */
  166.   setvect(8+1,_ev_keybdint);       /* so DV/X will work (it redirects) */
  167.  
  168.   if(use_DPMI)
  169.   {
  170.     enable();
  171.     return;
  172.   }
  173.  
  174.   if (old_master_lo == 0x08)
  175.   {
  176.     hard_master_lo = find_empty_pic();
  177.     if (vcpi_installed)
  178.       vcpi_set_pics(hard_master_lo, hard_slave_lo);
  179.     set_controller(hard_master_lo);
  180.     movedata(0, 0x08*4, 0, hard_master_lo*4, 0x08*4);
  181.   }
  182.   else
  183.   {
  184.     hard_master_lo = old_master_lo;
  185.   }
  186.   hard_master_hi = hard_master_lo + 7;
  187.  
  188.   enable();
  189.   vector_78h = hard_master_lo;
  190.   vector_79h = hard_master_lo + 1;
  191. }
  192.  
  193. void uninit_controllers(void)
  194. {
  195.   if(!cntrls_initted) return;
  196.   cntrls_initted = 0;
  197.   disable();
  198.  
  199.   movedata(_DS, FP_OFF(saved_interrupt_table), 0, 0, 256*4);
  200.  
  201.   if (old_master_lo == 0x08 && !use_DPMI)
  202.   {
  203.     if (vcpi_installed)
  204.       vcpi_set_pics(0x08, hard_slave_lo);
  205.     set_controller(0x08);
  206.   }
  207.   setvect(8+1,_ev_oldkbint);  /* not old_master_lo for XDV */
  208.   enable();
  209. }
  210.  
  211. static DPMIaddress exceptions[17];
  212. static DPMIaddress interrupt10;
  213. static DPMIaddress interrupt21;
  214. static DPMIaddress interrupt33;
  215. static DPMIaddress interrupt75;
  216.  
  217. void setDPMIvector(void)
  218. {
  219.   int i;
  220.   for (i = 0; i < sizeof(exceptions) / sizeof(*exceptions); ++i) {
  221.     DPMIehandler(i, &exceptions[i]);
  222.     DPMIchangeException(i, &exceptions[i]);
  223.   }
  224.   DPMIhandler(0x10, &interrupt10);
  225.   DPMIchangeInterrupt(0x10, &interrupt10);
  226.   DPMIhandler(0x21, &interrupt21);
  227.   DPMIchangeInterrupt(0x21, &interrupt21);
  228.   DPMIhandler(0x33, &interrupt33);
  229.   DPMIchangeInterrupt(0x33, &interrupt33);
  230.   DPMIhandlerNPX(&interrupt75);
  231.   DPMIchangeInterrupt(0x75, &interrupt75);
  232. }
  233.  
  234. void restoreDPMIvector(void)
  235. {
  236.   int i;
  237.   for (i = 0; i < sizeof(exceptions) / sizeof(*exceptions); ++i)
  238.     DPMIchangeException(i, &exceptions[i]);
  239.   DPMIchangeInterrupt(0x10, &interrupt10);
  240.   DPMIchangeInterrupt(0x21, &interrupt21);
  241.   DPMIchangeInterrupt(0x33, &interrupt33);
  242.   DPMIchangeInterrupt(0x75, &interrupt75);
  243. }
  244.  
  245. void tss2reg(struct REGPACK *r)
  246. {
  247.   r->r_ax = (word16)(tss_ptr->tss_eax);
  248.   r->r_bx = (word16)(tss_ptr->tss_ebx);
  249.   r->r_cx = (word16)(tss_ptr->tss_ecx);
  250.   r->r_dx = (word16)(tss_ptr->tss_edx);
  251.   r->r_si = (word16)(tss_ptr->tss_esi);
  252.   r->r_di = (word16)(tss_ptr->tss_edi);
  253.   r->r_flags = (word16)(tss_ptr->tss_eflags);
  254.   r->r_ds = r->r_es = _DS;
  255. }
  256.  
  257. void reg2tss(struct REGPACK *r)
  258. {
  259.   tss_ptr->tss_eax = r->r_ax;
  260.   tss_ptr->tss_ebx = r->r_bx;
  261.   tss_ptr->tss_ecx = r->r_cx;
  262.   tss_ptr->tss_edx = r->r_dx;
  263.   tss_ptr->tss_esi = r->r_si;
  264.   tss_ptr->tss_edi = r->r_di;
  265.   tss_ptr->tss_eflags = flmerge(r->r_flags, tss_ptr->tss_eflags);
  266. }
  267.  
  268. extern int ctrl_c_flag;
  269.  
  270. int double_fault(void)
  271. {
  272.   fprintf(stderr, "double fault!\n");
  273.   exit(1);
  274.   return 1;
  275. }
  276.  
  277. int check_nonpresent_387(void )
  278. {
  279.   if (!using_external_debugger)
  280.   {
  281.     fprintf(stderr, "Fatal!  Application attempted to use not-present 80387!\n");
  282.     fprintf(stderr, "Floating point opcode at virtual address 0x%08lx\n", tss_ptr->tss_eip);
  283.   }
  284.   return 1;
  285. }
  286.  
  287. int unsupported_int()
  288. {
  289.   if (!debug_mode)
  290.     fprintf(stderr, "Unsupported INT 0x%02x\n", tss_ptr->tss_irqn);
  291.   return 1;
  292. }
  293.  
  294. #define U unsupported_int
  295. typedef int (*FUNC)(void);
  296. static FUNC exception_handler_list[] = {
  297.   U, U, U, U, U, U, U,
  298.   /* 07 */ check_nonpresent_387,
  299.   /* 08 */ double_fault,
  300.   U, U, U, U, U,
  301.   /* 0e */ page_in,
  302.   U,
  303.   /* 10 */ i_10,        /* Video Interrupt */
  304.   /* 11 */ generic_handler,    /* Equipment detection */
  305.   /* 12 */ generic_handler,    /* Get memory size (outdated) */
  306.   U,
  307.   /* 14 */ generic_handler,    /* Serial communication */
  308.   /* 15 */ generic_handler,    /* Lots of strange things */
  309.   /* 16 */ generic_handler,    /* Keyboard */
  310.   /* 17 */ generic_handler,    /* Parallel printer */
  311.   U, U,
  312.   /* 1a */ generic_handler,    /* Get/set system time */
  313.   U, U, U, U, U, U,
  314.   /* 21 */ i_21,        /* DOS Services */
  315.   U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
  316.   /* 31 */ i_31,        /* DPMIsim */
  317.   U,
  318.   /* 33 */ i_33            /* Mouse */
  319. };
  320. #undef U
  321. #define NUM_EXCEPTIONS    (sizeof(exception_handler_list)/sizeof(exception_handler_list[0]))
  322.  
  323. exception_handler(void)
  324. {
  325.   int i;
  326.   if (topline_info)
  327.   {
  328.     char buf[20];
  329.     if (tss_ptr->tss_irqn == 14)
  330.       sprintf(buf, "0x%08lx", tss_ptr->tss_cr2 - ARENA);
  331.     else
  332.       sprintf(buf, "0x%08lx", tss_ptr->tss_eip);
  333.     for (i=0; buf[i]; i++)
  334.       poke(screen_seg, i*2+80, buf[i] | 0x0600);
  335.   }
  336.   i = tss_ptr->tss_irqn;
  337. /*  printf("i=%#02x\n", i); */
  338.   if (((i >= hard_slave_lo)  && (i <= hard_slave_hi)
  339.        && (i != hard_slave_lo + 5))
  340.       || ((i >= hard_master_lo) && (i <= hard_master_hi)))
  341.   {
  342.     in_hardware_interrupt = 1;
  343.     intr(i, &r);
  344.     in_hardware_interrupt = 0;
  345.     if (ctrl_break_hit)
  346.       return 1;
  347.     if (i == hard_master_lo + 1)
  348.     {
  349.       if (ctrl_c_causes_break)
  350.       {
  351.         r.r_ax = 0x0100;
  352.         intr(0x16, &r);
  353.         if (!(r.r_flags & 0x40) && (r.r_ax == 0x2e03))
  354.         {
  355.           _AH = 0;
  356.           geninterrupt(0x16);
  357.           ctrl_c_flag = 1;
  358.         }
  359.       }
  360.     }
  361.     if (ctrl_c_flag)
  362.     {
  363.       ctrl_c_flag = 0;
  364.       if (ctrl_c_causes_break)
  365.         return 1;
  366.     }
  367.     return 0;
  368.   }
  369.   if (i < NUM_EXCEPTIONS)
  370.     return (exception_handler_list[i])();
  371.   else
  372.     return 1;
  373. }
  374.  
  375. void retrieve_string(word32 v, char *transfer_buffer, char tchar)
  376. {
  377.   int i;
  378.   if (!use_DPMI) {
  379. #if 0
  380.     for (i=0; i<4096; i++)
  381.     {
  382.       c = peek8(v);
  383.       v++;
  384.       transfer_buffer[i] = c;
  385.       if (c == tchar)
  386.         break;
  387.     }
  388. #else
  389.     memscan32(v, transfer_buffer, tchar);
  390. #endif
  391.     return;
  392.   } else {
  393.     i = Pmemscan(tss_ptr->tss_ds, v, tchar, 4096);
  394.     if (i == 0) i = 4096;
  395.     Pmemget(tss_ptr->tss_ds, v, transfer_buffer, i);
  396.     return;
  397.   }
  398. }
  399.  
  400. generic_handler(void)
  401. {
  402.   tss2reg(&r);
  403.   intr(tss_ptr->tss_irqn, &r);
  404.   reg2tss(&r);
  405.   return 0;
  406. }
  407.  
  408. i_10(void)
  409. {
  410.   word32 v;
  411.   word16 i, j;
  412.  
  413. /* CB changes */
  414. /* OLD:
  415.  * switch((word16)(tss_ptr->tss_eax) & 0xFF00) {
  416.  *   case 0xFD00:
  417.  *     graphics_pageflip();
  418.  *     return 0;
  419.  *   case 0xFE00:
  420.  *     graphics_inquiry();
  421.  *     return 0;
  422.  *   case 0xFF00:
  423.  *     graphics_mode((word16)(tss_ptr->tss_eax) & 0xff);
  424.  *     in_graphics_mode = (peekb(0x40, 0x49) > 7);
  425.  *     return 0;
  426.  * }
  427.  */
  428.   if(((word16)tss_ptr->tss_eax & 0xff00) >= gr_assist_func_start) {
  429.     graphics_assist();
  430.     in_graphics_mode = (peekb(0x40, 0x49) > 7);
  431.     return 0;
  432.   }
  433. /* end CB changes */
  434.   tss2reg(&r);
  435.  
  436.   i = (word16)tss_ptr->tss_eax; /* int10 function 0x11 subfunctions 0 & 0x10 */
  437.   if(i==0x1100 || i==0x1110)
  438.   { /* user-defined text characters */
  439.     v = tss_ptr->tss_edx + ARENA; /* bh*cx bytes starting at (ds:dx) */
  440.     CHECK_SEGFAULT(v);
  441.     j = ((tss_ptr->tss_ebx >> 8) & 0xff) * ((word16)tss_ptr->tss_ecx);
  442.     memget(v, transfer_buffer, j);
  443.     r.r_dx = FP_OFF(transfer_buffer);
  444.     r.r_ds = _DS;
  445.   }
  446.  
  447.   intr(0x10, &r);
  448.   reg2tss(&r);
  449.   tss_ptr->tss_ebp = r.r_es * 16L + r.r_bp + 0xe0000000L;
  450.   return 0;
  451. }
  452.  
  453. #include "eventque.h"
  454.  
  455. #define  MSDRAW_STACK  128              /* stack size for mouse callback */
  456.  
  457. static word32  mousedraw_func32;        /* 32-bit mouse cursor drawing function */
  458. static word32  mousedraw_contaddr;      /* jump to this address after mouse draw */
  459. static char    mousedraw_active;        /* set while drawing mouse cursor */
  460. EventQueue    *event_queue = NULL;      /* event queue */
  461. typedef int far (*FFUNC)(void);
  462. static FFUNC   mousedraw_callback = 0;    /* DPMI real mode callback to prot */
  463.  
  464. static void mousedraw_hook(void)
  465. {
  466.   disable();
  467.   if(!mousedraw_active)
  468.   {
  469.     mousedraw_active = 1;
  470.     if(use_DPMI)
  471.     {
  472.       mousedraw_callback();
  473.       mousedraw_active = 0;
  474.     }
  475.     else
  476.     {
  477.       mousedraw_contaddr = a_tss.tss_eip;
  478.       a_tss.tss_eip = mousedraw_func32;
  479.     }
  480.   }
  481.   enable();
  482. }
  483.  
  484. i_33(void)
  485. {
  486.   void (*msdrawfun)(void);
  487.   int  queuesize;
  488.  
  489.   if(tss_ptr->tss_eax == 0x00ff) {
  490.     if(event_queue != NULL) {
  491.       EventQueueDeInit();
  492.       event_queue = NULL;
  493.     }
  494.     if((queuesize = (int)tss_ptr->tss_ebx) > 0) {
  495.       mousedraw_func32 = tss_ptr->tss_ecx;
  496.       mousedraw_active = 0;
  497.       msdrawfun = (mousedraw_func32 != 0L) ? mousedraw_hook : NULL;
  498.       if(use_DPMI) {
  499.         if(tss_ptr->tss_edx != 0x12345678L) return(0);    /* make sure V1.03 or more */
  500.         mousedraw_callback = (FFUNC)mousedraw_func32;
  501.       }
  502.       event_queue = EventQueueInit(queuesize, MSDRAW_STACK, msdrawfun);
  503.       if(event_queue != NULL) {
  504.         tss_ptr->tss_ebx =
  505.           (((word32)FP_SEG(event_queue)) << 4) +
  506.           ((word32)FP_OFF(event_queue)) +
  507.           0xe0000000L;
  508.         tss_ptr->tss_ecx =
  509.           (((word32)FP_SEG(&mousedraw_contaddr)) << 4) +
  510.           ((word32)FP_OFF(&mousedraw_contaddr)) +
  511.           0xe0000000L;
  512.         tss_ptr->tss_edx =
  513.           (((word32)FP_SEG(&mousedraw_active)) << 4) +
  514.           ((word32)FP_OFF(&mousedraw_active)) +
  515.           0xe0000000L;
  516.       }
  517.       else tss_ptr->tss_ebx = 0L;
  518.     }
  519.     tss_ptr->tss_eax = 0x0ff0;              /* acknowledge event handling */
  520.     return(0);
  521.   }
  522.   if (*((unsigned far *)0x000000CEL) == 0)
  523.     return 0;
  524.   r.r_ax = (word16)(tss_ptr->tss_eax);
  525.   r.r_bx = (word16)(tss_ptr->tss_ebx);
  526.   r.r_cx = (word16)(tss_ptr->tss_ecx);
  527.   r.r_dx = (word16)(tss_ptr->tss_edx);
  528.   intr(0x33, &r);
  529.   tss_ptr->tss_eax = r.r_ax;
  530.   tss_ptr->tss_ebx = r.r_bx;
  531.   tss_ptr->tss_ecx = r.r_cx;
  532.   tss_ptr->tss_edx = r.r_dx;
  533.   return 0;
  534. }
  535.  
  536. /*1.07 TSS last_tss; */
  537.  
  538. i_21(void)
  539. {
  540.   word32 v, trans_total, countleft;
  541.   int i, c, ah, tchar, trans_count;
  542.   char *cp;
  543.   tss2reg(&r);
  544.   ah = ((word16)(tss_ptr->tss_eax) >> 8) & 0xff;
  545.  
  546.   if (ah & 0x80) switch (ah)
  547.   {
  548.     case 0xfe:
  549.       return external_debugger_handler();
  550.     case 0xff:
  551.       return turbo_assist();
  552.     default:
  553.       return 1;
  554.   }
  555.   else switch (ah)
  556.   {
  557.     case 1: /* read with echo */
  558.     case 2: /* con output */
  559.     case 3: /* aux input */
  560.     case 4: /* aux output */
  561.     case 5: /* prn output */
  562.     case 6: /* direct con i/o */
  563.     case 7: /* direct con input */
  564.     case 8: /* kbd read */
  565.     case 0x0b: /* kbd status */
  566.     case 0x0d: /* reset disk */
  567.     case 0x0e: /* select disk */
  568.     case 0x18: /* return al=0 */
  569.     case 0x19: /* get disk */
  570.     case 0x1d: /* return al=0 */
  571.     case 0x1e: /* return al=0 */
  572.     case 0x20: /* return al=0 */
  573.     case 0x2a: /* get date */
  574.     case 0x2b: /* set date */
  575.     case 0x2c: /* get time */
  576.     case 0x2d: /* set time */
  577.     case 0x2e: /* (re)set verify flag */
  578.     case 0x30: /* get version */
  579.     case 0x36: /* get disk free space */
  580.     case 0x37: /* get/set switch char */
  581.     case 0x42: /* seek */
  582.     case 0x4d: /* get return code */
  583.     case 0x54: /* get verify flag */
  584.     case 0x57: /* get/set file time stamp */
  585.     case 0x58: /* get/set UMB link state */
  586.     case 0x5c: /* file locking */
  587.     case 0x66: /* get/set global code page */
  588.     case 0x67: /* set handle count */
  589.     case 0x68: /* commit (flush and update directory) */
  590.       intr(0x21, &r);
  591.       reg2tss(&r);
  592.       return 0;
  593.     case 0x38: /* get country info */
  594.       r.r_ds = _DS;
  595.       r.r_dx = FP_OFF(transfer_buffer);
  596.       intr(0x21, &r);
  597.       if (r.r_flags & 1) 
  598.       {
  599.         tss_ptr->tss_eflags |= 1;
  600.         tss_ptr->tss_eax = r.r_ax;
  601.         return 0;
  602.       }
  603.       memput(tss_ptr->tss_edx + ARENA, transfer_buffer, 34);
  604.       return 0;
  605.     case 0x33: /* ^C checking and more */
  606.       switch (r.r_ax & 0xff) 
  607.       {
  608.       case 0x01: /* set ^C */
  609.       case 0x02: /* set extended ^C */
  610.     ctrl_c_causes_break = r.r_dx & 0xff;
  611.     /* fall through */
  612.       case 0x00: /* get ^C */
  613.       case 0x05: /* get boot drive */
  614.       case 0x06: /* get true dos version */
  615.     intr(0x21, &r);
  616.     reg2tss(&r);
  617.     return 0;
  618.       default:
  619.     return 1;
  620.       }
  621.     case 0x3e: /* close */
  622.       if (using_external_debugger && r.r_bx < 2)
  623.         return 0;
  624.       if (r.r_bx == 1)
  625.         redir_1_mono = redir_1_2 = 0;
  626.       if (r.r_bx == 2)
  627.         redir_2_mono = redir_2_1 = 0;
  628.       intr(0x21, &r);
  629.       reg2tss(&r);
  630.       return 0;
  631.     case 9: /* print string */
  632.     case 0x39: /* mkdir */
  633.     case 0x3a: /* rmdir */
  634.     case 0x3b: /* chdir */
  635.     case 0x41: /* unlink (delete) */
  636.     case 0x43: /* chmod */
  637.       if (ah == 9)
  638.         tchar = '$';
  639.       else
  640.         tchar = 0;
  641.       v = tss_ptr->tss_edx + ARENA;
  642.       CHECK_SEGFAULT(v);
  643.       retrieve_string(v, transfer_buffer, tchar);
  644.       r.r_dx = FP_OFF(transfer_buffer);
  645.       r.r_ds = _DS;
  646.       intr(0x21, &r);
  647.       reg2tss(&r);
  648.       return 0;
  649.     case 0x3c: /* creat (rewrite) */
  650.       v = tss_ptr->tss_edx + ARENA;
  651.       CHECK_SEGFAULT(v);
  652.       retrieve_string(v, transfer_buffer, 0);
  653.       i = _creat(transfer_buffer, (int)(tss_ptr->tss_ecx));
  654.       if (i < 0)
  655.       {
  656.         tss_ptr->tss_eax = errno;
  657.         tss_ptr->tss_eflags |= 1;
  658.       }
  659.       else
  660.       {
  661.         tss_ptr->tss_eax = i;
  662.         tss_ptr->tss_eflags &= ~1;
  663.       }
  664.       return 0;
  665.     case 0x3d: /* open */
  666.       v = tss_ptr->tss_edx + ARENA;
  667.       CHECK_SEGFAULT(v)
  668.       retrieve_string(v, transfer_buffer, 0);
  669.       i = (word16)(tss_ptr->tss_eax) & 0xf0;
  670.       if (tss_ptr->tss_eax & O_WRONLY) i |= 1;
  671.       if (tss_ptr->tss_eax & O_RDWR) i |= 2;
  672.       i = _open(transfer_buffer, i);
  673.       if (i < 0)
  674.       {
  675.         tss_ptr->tss_eax = errno;
  676.         tss_ptr->tss_eflags |= 1;
  677.       }
  678.       else
  679.       {
  680.         tss_ptr->tss_eax = i;
  681.         tss_ptr->tss_eflags &= ~1;
  682.       }
  683.       return 0;
  684.     case 0x1a: /* set dta */
  685.       user_dta = tss_ptr->tss_edx;
  686.       setdta((char far *)transfer_buffer);
  687.       return 0;
  688.     case 0x2f: /* get dta */
  689.       tss_ptr->tss_ebx = user_dta;
  690.       return 0;
  691.     case 0x56: /* rename/move */
  692.       v = tss_ptr->tss_edx + ARENA;
  693.       CHECK_SEGFAULT(v)
  694.       retrieve_string(v, transfer_buffer, 0);
  695.       i = strlen(transfer_buffer) + 1;
  696.       r.r_dx = FP_OFF(transfer_buffer);
  697.       r.r_ds = _DS;
  698.       v = tss_ptr->tss_edi + ARENA;
  699.       retrieve_string(v, transfer_buffer+i, 0);
  700.       r.r_di = FP_OFF(transfer_buffer)+i;
  701.       r.r_es = _DS;
  702.       intr(0x21, &r);
  703.       tss_ptr->tss_eax = r.r_ax;
  704.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  705.       return 0;
  706.     case 0x3f: /* read */
  707.       if (!tss_ptr->tss_edx) {
  708.         fprintf(stderr, "This image has a buggy read.s module.  Run DPMIFIX on it and try again.\n");
  709.         return 1;
  710.       }
  711.       if (tss_ptr->tss_edx == transfer_linear)
  712.       {
  713.         i = read(r.r_bx, transfer_buffer, r.r_cx);
  714.         if (i<0)
  715.         {
  716.           tss_ptr->tss_eflags |= 1; /* carry */
  717.           tss_ptr->tss_eax = _doserrno;
  718.         }
  719.         else
  720.         {
  721.           tss_ptr->tss_eflags &= ~1;
  722.           tss_ptr->tss_eax = i;
  723.         }
  724.         return 0;
  725.       }
  726.       trans_total = 0;
  727.       countleft = tss_ptr->tss_ecx;
  728.       v = tss_ptr->tss_edx;
  729.       CHECK_SEGFAULT(v+ARENA)
  730.       while (countleft > 0)
  731.       {
  732.         trans_count = (word16)((countleft <= 4096) ? countleft : 4096);
  733.         i = read(r.r_bx, transfer_buffer, trans_count);
  734.         if (i < 0)
  735.         {
  736.           tss_ptr->tss_eflags |= 1; /* carry */
  737.           tss_ptr->tss_eax = _doserrno;
  738.           return 0;
  739.         }
  740.         memput(v+ARENA, transfer_buffer, i);
  741.         trans_total += i;
  742.         v += i;
  743.         countleft -= i;
  744.         if (isatty(r.r_bx) && (i<trans_count))
  745.           break; /* they're line buffered */
  746.         if (i == 0)
  747.           break;
  748.       }
  749.       tss_ptr->tss_eax = trans_total;
  750.       tss_ptr->tss_eflags &= ~1;
  751.       return 0;
  752.     case 0x40: /* write */
  753.       if (tss_ptr->tss_edx == transfer_linear)
  754.       {
  755.         if ((r.r_bx == 1) && redir_1_mono)
  756.           i = mono_write(transfer_buffer, r.r_cx);
  757.         else if ((r.r_bx == 2) && redir_2_mono)
  758.           i = mono_write(transfer_buffer, r.r_cx);
  759.         else
  760.         {
  761.           int fd = r.r_bx;
  762.           if ((r.r_bx == 2) && redir_2_1)
  763.             fd = 1;
  764.           else if ((r.r_bx == 1) && redir_1_2)
  765.             fd = 2;
  766.           if (r.r_cx == 0) /* for ftruncate */
  767.             i = _write(fd, transfer_buffer, r.r_cx);
  768.           else
  769.             i = write(fd, transfer_buffer, r.r_cx);
  770.         }
  771.         if (i<0)
  772.         {
  773.           tss_ptr->tss_eflags |= 1; /* carry */
  774.           tss_ptr->tss_eax = _doserrno;
  775.         }
  776.         else
  777.         {
  778.           tss_ptr->tss_eflags &= ~1;
  779.           tss_ptr->tss_eax = i;
  780.         }
  781.         return 0;
  782.       }
  783.       trans_total = 0;
  784.       countleft = tss_ptr->tss_ecx;
  785.       if (countleft == 0)
  786.       {
  787.         r.r_ax = 0x4000;
  788.         r.r_cx = 0;
  789.         intr(0x21,&r);
  790.         tss_ptr->tss_eax = 0;
  791.         tss_ptr->tss_eflags &= ~1;
  792.         return 0;
  793.       }
  794.       v = tss_ptr->tss_edx;
  795.       CHECK_SEGFAULT(v+ARENA);
  796.       r.r_dx = (int)transfer_buffer;
  797.       while (countleft > 0)
  798.       {
  799.         trans_count = (word16)((countleft <= 4096) ? countleft : 4096);
  800.         memget(v+ARENA, transfer_buffer, trans_count);
  801.         if ((r.r_bx == 1) && redir_1_mono)
  802.           i = mono_write(transfer_buffer, trans_count);
  803.         else if ((r.r_bx == 2) && redir_2_mono)
  804.           i = mono_write(transfer_buffer, trans_count);
  805.         else
  806.         {
  807.           int fd = r.r_bx;
  808.           if ((r.r_bx == 2) && redir_2_1)
  809.             fd = 1;
  810.           else if ((r.r_bx == 1) && redir_1_2)
  811.             fd = 2;
  812.           i = write(fd, transfer_buffer, trans_count);
  813.           if (in_graphics_mode && (fd < 3))
  814.           {
  815.             word32 far *p = graphics_pt;
  816.             for (c = 0; c < 256; c++)
  817.               *p++ &= ~PT_P;
  818.           }
  819.         }
  820.         if (i<0) /* carry */
  821.         {
  822.           tss_ptr->tss_eflags |= 1; /* carry */
  823.           tss_ptr->tss_eax = _doserrno;
  824.           return 0;
  825.         }
  826.         trans_total += i;
  827.         v += i;
  828.         countleft -= i;
  829.         if (i < trans_count)
  830.           break;
  831.       }
  832.       tss_ptr->tss_eax = trans_total;
  833.       tss_ptr->tss_eflags &= ~1;
  834.       return 0;
  835.     case 0x44: /* ioctl */
  836.       return i_21_44();
  837.     case 0x45: /* dup */
  838.       i = r.r_bx;
  839.       intr(0x21, &r);
  840.       if (!(r.r_flags & 1))
  841.         _openfd[r.r_ax] = i;
  842.       reg2tss(&r);
  843.       return 0;
  844.     case 0x46: /* dup2 */
  845.       i = r.r_bx;
  846.       c = r.r_cx;
  847.       intr(0x21, &r);
  848.       if (!(r.r_flags & 1))
  849.         _openfd[c] = i;
  850.       reg2tss(&r);
  851.       return 0;
  852.     case 0x4e: /* find first */
  853.       CHECK_SEGFAULT(user_dta+ARENA);
  854.       v = tss_ptr->tss_edx + ARENA;
  855.       CHECK_SEGFAULT(v);
  856.       retrieve_string(v, transfer_buffer+43, 0);
  857.       r.r_dx = FP_OFF(transfer_buffer+43);
  858.       r.r_ds = _DS;
  859.       intr(0x21, &r);
  860.       reg2tss(&r);
  861.       for (i=20; i>=0; i--)
  862.         transfer_buffer[i+28] = transfer_buffer[i+26];
  863.       transfer_buffer[32+13] = 0; /* asciiz termination */
  864.       memput(user_dta+ARENA, transfer_buffer, 48);
  865.       return 0;
  866.     case 0x4f: /* find next */
  867.       CHECK_SEGFAULT(user_dta+ARENA);
  868.       memget(user_dta+ARENA, transfer_buffer, 48);
  869.       for (i=0; i<=20; i++)
  870.         transfer_buffer[i+26] = transfer_buffer[i+28];
  871.       intr(0x21, &r);
  872.       reg2tss(&r);
  873.       for (i=20; i>=0; i--)
  874.         transfer_buffer[i+28] = transfer_buffer[i+26];
  875.       transfer_buffer[32+13] = 0; /* asciiz termination */
  876.       memput(user_dta+ARENA, transfer_buffer, 48);
  877.       return 0;
  878.     case 0x47: /* getwd */
  879.       getcurdir((int)(tss_ptr->tss_edx & 0xff), transfer_buffer);
  880.       for (cp=transfer_buffer; *cp; cp++)
  881.       {
  882.         if (*cp == '\\') *cp = '/';
  883.         *cp = tolower(*cp);
  884.       }
  885.       memput(tss_ptr->tss_esi+ARENA, transfer_buffer, strlen(transfer_buffer)+1);
  886.       tss_ptr->tss_eax = (unsigned)r.r_ax;
  887.       tss_ptr->tss_eflags &= ~1;
  888.       return 0;
  889.     case 0x4a: /* sbrk/brk -- NOT ORGINAL MEANING */
  890.       if (tss_ptr->tss_eax & 0xff)
  891.         tss_ptr->tss_eax = paging_sbrk(tss_ptr->tss_ebx);
  892.       else
  893.         tss_ptr->tss_eax = paging_brk(tss_ptr->tss_ebx);
  894.       return 0;
  895.     case 0x4c: /* exit */
  896.       if (using_external_debugger)
  897.         return 1;
  898.       else
  899.         exit((word8)(tss_ptr->tss_eax));
  900.     default:
  901.       return 1;
  902.   }
  903. }
  904.  
  905. static int reg2gate(word32 r)
  906. {
  907.   int g = (int)(r & 0xff);
  908.   if (g >= 0x08 && g <= 0x0f)
  909.     g = g - 0x08 + hard_master_lo;
  910.   else if (g >= 0x70 && g <= 0x77)
  911.     g = g - 0x70 + hard_slave_lo;
  912.   return g;
  913. }
  914.  
  915. static int dpmisim_is_exec = 0;
  916.  
  917. int i_31(void)
  918. {
  919.   int gate, i;
  920.   word16 far *fptr;
  921.   word16 dpmisim_spare_stack[128];
  922.   union REGS r;
  923.   struct SREGS s;
  924.   switch ((word16)(tss_ptr->tss_eax))
  925.   {
  926.     case 0x0100:
  927.       r.h.ah = 0x48;
  928.       r.x.bx = (word16)tss_ptr->tss_ebx;
  929.       int86(0x21, &r, &r);
  930.       if ((r.x.flags & 1) && ((word16)tss_ptr->tss_ebx != 0xffff))
  931.       {
  932.         valloc_shrink_rmem(((word16)tss_ptr->tss_ebx)/256 + 1);
  933.         r.h.ah = 0x48;
  934.         r.x.bx = (word16)tss_ptr->tss_ebx;
  935.         int86(0x21, &r, &r);
  936. /*        if (r.x.flags & 1)
  937.           printf("biggest after shrinking is %04x\n", r.x.bx); */
  938.       }
  939.       tss_ptr->tss_eflags &= ~1;
  940.       tss_ptr->tss_eflags |= r.x.flags & 1;
  941.       tss_ptr->tss_edx =
  942.       tss_ptr->tss_eax = r.x.ax;
  943.       tss_ptr->tss_ebx = r.x.bx;
  944. /*      printf("allocated %x, %d %x\n", r.x.ax, r.x.flags & 1, r.x.bx); */
  945.       return 0;
  946.  
  947.     case 0x0101:
  948.       r.h.ah = 0x49;
  949.       r.x.bx = (word16)tss_ptr->tss_edx;
  950.       int86(0x21, &r, &r);
  951. /*      printf("released %x, %d %x\n", (word16)tss_ptr->tss_edx, r.x.flags & 1, r.x.ax); */
  952.       return 0;
  953.  
  954.     case 0x0102:
  955.       r.h.ah = 0x4a;
  956.       r.x.bx = (word16)tss_ptr->tss_ebx;
  957.       s.es = (word16)tss_ptr->tss_edx;
  958.       int86x(0x21, &r, &r, &s);
  959.       tss_ptr->tss_eflags &= ~1;
  960.       tss_ptr->tss_eflags |= r.x.flags & 1;
  961.       tss_ptr->tss_eax = r.x.ax;
  962.       tss_ptr->tss_ebx = r.x.bx;
  963.       return 0;
  964.  
  965.     case 0x0200:
  966.       gate = (word8)tss_ptr->tss_ebx;
  967.       tss_ptr->tss_ecx = peek(0, gate*4+2);
  968.       tss_ptr->tss_edx = peek(0, gate*4);
  969.       tss_ptr->tss_eflags &= ~1;
  970.       return 0;
  971.  
  972.     case 0x0201:
  973.       gate = (word8)tss_ptr->tss_ebx;
  974.       disable();
  975.       poke(0, gate*4+2, tss_ptr->tss_ecx);
  976.       poke(0, gate*4, tss_ptr->tss_edx);
  977.       enable();
  978.       tss_ptr->tss_eflags &= ~1;
  979.       return 0;
  980.  
  981.     case 0x0204:
  982.       gate = reg2gate(tss_ptr->tss_ebx);
  983.       tss_ptr->tss_ecx = idt[gate].selector;
  984.       tss_ptr->tss_edx = idt[gate].offset0 | (idt[gate].offset1 << 16);
  985.       tss_ptr->tss_eflags &= ~1;
  986.       return 0;
  987.  
  988.     case 0x0205:
  989.       gate = reg2gate(tss_ptr->tss_ebx);
  990.       idt[gate].selector = (word16)(tss_ptr->tss_ecx);
  991.       idt[gate].offset0 = (word16)(tss_ptr->tss_edx);
  992.       idt[gate].offset1 = (word16)(tss_ptr->tss_edx >> 16);
  993.       idt[gate].stype = 0x8e00;
  994.       tss_ptr->tss_eflags &= ~1;
  995.       return 0;
  996.  
  997.     case 0x0300:
  998.     case 0x0301:
  999.     case 0x0302:
  1000.       CHECK_SEGFAULT(tss_ptr->tss_edi + ARENA);
  1001.       if (tss_ptr->tss_ecx)
  1002.       {
  1003.         tss_ptr->tss_eax = 0x8021;
  1004.         tss_ptr->tss_eflags |= 1;
  1005.         return 0;
  1006.       }
  1007.       memget(tss_ptr->tss_edi + ARENA, dpmisim_regs, 50);
  1008.  
  1009.       if (dpmisim_regs[24] == 0)
  1010.       {
  1011.         dpmisim_regs[24] = _SS;
  1012.         dpmisim_regs[23] = (word16)(dpmisim_spare_stack) + sizeof(dpmisim_spare_stack);
  1013.       }
  1014.       if ((word16)tss_ptr->tss_eax != 0x0301)
  1015.       {
  1016.         dpmisim_regs[23] -= 2;    /* fake pushing flags on stack */
  1017.         fptr = MK_FP(dpmisim_regs[24], dpmisim_regs[23]);
  1018.         *fptr = dpmisim_regs[16];
  1019.       }
  1020.  
  1021.       if ((word16)tss_ptr->tss_eax == 0x0300)
  1022.       {
  1023.         dpmisim_regs[21] = peek(0, (word8)tss_ptr->tss_ebx * 4);
  1024.         dpmisim_regs[22] = peek(0, (word8)tss_ptr->tss_ebx * 4 + 2);
  1025.       }
  1026.  
  1027.       if (dpmisim_is_exec)
  1028.       {
  1029.         word32 our_interrupt_table[256];
  1030.         page_out_everything();
  1031.         movedata(0, 0, FP_SEG(our_interrupt_table), FP_OFF(our_interrupt_table), 256*4);
  1032.         uninit_controllers();
  1033.         dpmisim();
  1034.         init_controllers();
  1035.         disable();
  1036.         movedata(FP_SEG(our_interrupt_table), FP_OFF(our_interrupt_table), 0, 0, 256*4);
  1037.         enable();
  1038.        page_in_everything();
  1039.       }
  1040.       else
  1041.         dpmisim();
  1042.  
  1043.       memput(tss_ptr->tss_edi + ARENA, dpmisim_regs, 50);
  1044.       tss_ptr->tss_eflags &= ~1;
  1045.       return 0;
  1046.  
  1047.     case 0x0303:
  1048.       CHECK_SEGFAULT(tss_ptr->tss_edi + ARENA);
  1049.       for (i=0; i<16; i++)
  1050.         if (dpmisim_rmcb[i].cb_address == 0)
  1051.           break;
  1052.       if (i == 16)
  1053.       {
  1054.         tss_ptr->tss_eflags |= 1;
  1055.         tss_ptr->tss_eax = 0x8015;
  1056.         return 0;
  1057.       }
  1058.       dpmisim_rmcb[i].cb_address = tss_ptr->tss_esi;
  1059.       dpmisim_rmcb[i].reg_ptr = tss_ptr->tss_edi;
  1060.       tss_ptr->tss_eflags &= ~1;
  1061.       tss_ptr->tss_ecx = _CS;
  1062.       tss_ptr->tss_edx = (word16)dpmisim_rmcb0 + i * ((word16)dpmisim_rmcb1 - (word16)dpmisim_rmcb0);
  1063.       return 0;
  1064.  
  1065.     case 0x0304:
  1066.       if ((word16)tss_ptr->tss_ecx == _CS)
  1067.         for (i=0; i<16; i++)
  1068.           if ((word16)tss_ptr->tss_edx == (word16)dpmisim_rmcb0 + i * ((word16)dpmisim_rmcb1 - (word16)dpmisim_rmcb0))
  1069.           {
  1070.             dpmisim_rmcb[i].cb_address = 0;
  1071.             tss_ptr->tss_eflags &= ~1;
  1072.             return 0;
  1073.           }
  1074.       tss_ptr->tss_eflags |= 1;
  1075.       tss_ptr->tss_eax = 0x8024;
  1076.       return 0;
  1077.       
  1078.     case 0x0500:
  1079.       CHECK_SEGFAULT(tss_ptr->tss_edi + ARENA);
  1080.       memset(transfer_buffer, 0xff, 48);
  1081.       ((word32 *)transfer_buffer)[8] = dalloc_max_size();
  1082.       ((word32 *)transfer_buffer)[4] =
  1083.       ((word32 *)transfer_buffer)[6] = valloc_max_size();
  1084.       ((word32 *)transfer_buffer)[2] =
  1085.       ((word32 *)transfer_buffer)[5] = valloc_max_size() - valloc_used();
  1086.       ((word32 *)transfer_buffer)[1] = 
  1087.         ((word32 *)transfer_buffer)[5] + ((word32 *)transfer_buffer)[8] - dalloc_used();
  1088.       ((word32 *)transfer_buffer)[0] = ((word32 *)transfer_buffer)[1] * 4096L;
  1089.       memput(tss_ptr->tss_edi + ARENA, transfer_buffer, 48);
  1090.       tss_ptr->tss_eflags &= ~1;
  1091.       return 0;
  1092.  
  1093.     default: /* mark as unsupported */
  1094.       tss_ptr->tss_eflags |= 1;
  1095.       tss_ptr->tss_eax = 0x8001;
  1096.       return 0;
  1097.   }
  1098. }
  1099.  
  1100. struct time32 {
  1101.   word32 secs;
  1102.   word32 usecs;
  1103. };
  1104.  
  1105. struct tz32 {
  1106.   word32 offset;
  1107.   word32 dst;
  1108. };
  1109.  
  1110. struct  stat32 {
  1111.         short st_dev;
  1112.         short st_ino;
  1113.         short st_mode;
  1114.         short st_nlink;
  1115.         short st_uid;
  1116.         short st_gid;
  1117.         short st_rdev;
  1118.         short st_align_for_word32;
  1119.         long  st_size;
  1120.         long  st_atime;
  1121.         long  st_mtime;
  1122.         long  st_ctime;
  1123.         long  st_blksize;
  1124. };
  1125.  
  1126. static int dev_count=1;
  1127.  
  1128. turbo_assist(void)
  1129. {
  1130.   word32 p1, p2, r;
  1131.   struct time32 time32;
  1132.   struct tz32 tz32;
  1133.   struct stat32 statbuf32;
  1134.   struct stat statbuf;
  1135.   int i;
  1136.   char buf[128], *bp;
  1137.   word32 our_interrupt_table[256];
  1138.  
  1139.   p1 = tss_ptr->tss_ebx;
  1140.   p2 = tss_ptr->tss_ecx;
  1141.   switch ((word8)(tss_ptr->tss_eax))
  1142.   {
  1143.     case 1: /* creat */
  1144.       retrieve_string(p1+ARENA, buf, 0);
  1145.       r = creat(buf, S_IREAD | S_IWRITE);
  1146.       break;
  1147.  
  1148.     case 2: /* open */
  1149.       retrieve_string(p1+ARENA, buf, 0);
  1150.       r = open(buf, (int)p2, S_IREAD | S_IWRITE);
  1151.       break;
  1152.  
  1153.     case 3: /* fstat */
  1154.       memset(&statbuf, 0, sizeof(statbuf));
  1155.       r = fstat((int)p1, &statbuf);
  1156.       statbuf32.st_dev = dev_count++;
  1157.       statbuf32.st_ino = statbuf.st_ino;
  1158.       statbuf32.st_mode = statbuf.st_mode;
  1159.       statbuf32.st_nlink = statbuf.st_nlink;
  1160.       statbuf32.st_uid = 42;
  1161.       statbuf32.st_gid = 42;
  1162.       statbuf32.st_rdev = statbuf.st_rdev;
  1163.       statbuf32.st_size = statbuf.st_size;
  1164.       statbuf32.st_atime = statbuf.st_atime;
  1165.       statbuf32.st_mtime = statbuf.st_mtime;
  1166.       statbuf32.st_ctime = statbuf.st_ctime;
  1167.       statbuf32.st_blksize = 512;
  1168.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  1169.       break;
  1170.  
  1171.     case 4: /* gettimeofday */
  1172.       if (p2)
  1173.       {
  1174.         CHECK_SEGFAULT(p2+ARENA);
  1175.         tz32.offset = timezone;
  1176.         tz32.dst = daylight;
  1177.         memput(p2+ARENA, &tz32, sizeof(tz32));
  1178.       }
  1179.       if (p1)
  1180.       {
  1181.         int dh;
  1182.         CHECK_SEGFAULT(p1+ARENA);
  1183.         time((long *)&(time32.secs));
  1184.         _AH = 0x2c;
  1185.         geninterrupt(0x21);
  1186.         dh = _DH;
  1187.         time32.usecs = _DL * 10000L;
  1188.         if (time32.secs % 60 != dh)
  1189.           time32.secs++;
  1190.         memput(p1+ARENA, &time32, sizeof(time32));
  1191.       }
  1192.       r = 0;
  1193.       break;
  1194.  
  1195.     case 5: /* settimeofday */
  1196.       if (p2)
  1197.       {
  1198.         CHECK_SEGFAULT(p2+ARENA);
  1199.         memget(p2+ARENA, &tz32, sizeof(tz32));
  1200.         timezone = tz32.offset;
  1201.         daylight = (int)tz32.dst;
  1202.       }
  1203.       if (p1)
  1204.       {
  1205.         CHECK_SEGFAULT(p1+ARENA);
  1206.         memget(p1+ARENA, &time32, sizeof(time32));
  1207.         stime((long *)&(time32.secs));
  1208.       }
  1209.       r = 0;
  1210.       break;
  1211.  
  1212.     case 6: /* stat */
  1213.       memset(&statbuf, 0, sizeof(statbuf));
  1214.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  1215.       r = unixlike_stat(transfer_buffer, &statbuf);
  1216.       statbuf32.st_dev = dev_count++;
  1217.       statbuf32.st_ino = statbuf.st_ino;
  1218.       statbuf32.st_mode = statbuf.st_mode;
  1219.       statbuf32.st_nlink = statbuf.st_nlink;
  1220.       statbuf32.st_uid = statbuf.st_uid;
  1221.       statbuf32.st_gid = statbuf.st_gid;
  1222.       statbuf32.st_rdev = statbuf.st_rdev;
  1223.       statbuf32.st_size = statbuf.st_size;
  1224.       statbuf32.st_atime = statbuf.st_atime;
  1225.       statbuf32.st_mtime = statbuf.st_mtime;
  1226.       statbuf32.st_ctime = statbuf.st_ctime;
  1227.       statbuf32.st_blksize = 512;
  1228.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  1229.       break;
  1230.  
  1231.     case 7: /* system */
  1232.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  1233.       page_out_everything();
  1234.       movedata(0, 0, FP_SEG(our_interrupt_table), FP_OFF(our_interrupt_table), 256*4);
  1235.       uninit_controllers();
  1236.       sscanf(transfer_buffer, "%s%n", buf, &i);
  1237.       if (strpbrk(transfer_buffer, "<>|") == NULL)
  1238.         r = spawnlp(P_WAIT, buf, buf, transfer_buffer+i, 0);
  1239.       else
  1240.         r = -1;
  1241.       bp = buf+strlen(buf)-4;
  1242.       if (stricmp(bp, ".exe") && stricmp(bp, ".com") && (r & 0x80000000L))
  1243.         r = system(transfer_buffer);
  1244.       init_controllers();
  1245.       disable();
  1246.       movedata(FP_SEG(our_interrupt_table), FP_OFF(our_interrupt_table), 0, 0, 256*4);
  1247.       enable();
  1248.       page_in_everything();
  1249.       break;
  1250.  
  1251.     case 8: /* _setmode() */
  1252.       _BX=(int)p1;
  1253.       _AX=0x4400;
  1254.       geninterrupt(0x21);
  1255.       i = _DX;
  1256.       if (p2 & O_BINARY)
  1257.         i |= 0x20;
  1258.       else
  1259.         i &= ~0x20;
  1260.       _BX=(int)p1;
  1261.       _DX = i;
  1262.       _AX=0x4401;
  1263.       geninterrupt(0x21);
  1264.       r = setmode((int)p1, (int)p2);
  1265.       break;
  1266.  
  1267.     case 9: /* chmod */
  1268.       retrieve_string(p1+ARENA, buf, 0);
  1269.       r = chmod(buf, (int)p2);
  1270.       break;
  1271.  
  1272.     case 10: /* DPMI exec */
  1273.       dpmisim_is_exec = 1;
  1274.       tss_ptr->tss_eax = 0x0300;
  1275.       i_31();
  1276.       dpmisim_is_exec = 0;
  1277.       return 0;
  1278.  
  1279.     default:
  1280.       return 1;
  1281.   }
  1282.   tss_ptr->tss_eflags &= ~1;
  1283.   if (r == -1)
  1284.   {
  1285.     tss_ptr->tss_eflags |= 1;
  1286.     tss_ptr->tss_eax = errno;
  1287.     return 0;
  1288.   }
  1289.   tss_ptr->tss_eax = r;
  1290.   return 0;
  1291. }
  1292.  
  1293. i_21_44(void)
  1294. {
  1295.   switch ((word8)(tss_ptr->tss_eax))
  1296.   {
  1297.     case 0x00:
  1298.     case 0x01:
  1299.     case 0x06:
  1300.     case 0x07:
  1301.     case 0x08:
  1302.     case 0x09:
  1303.     case 0x0a:
  1304.     case 0x0b:
  1305.     case 0x0e:
  1306.     case 0x0f:
  1307.       intr(0x21, &r);
  1308.       tss_ptr->tss_edx = r.r_dx;
  1309.       tss_ptr->tss_eax = r.r_ax;
  1310.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  1311.       return 0;
  1312.     default:
  1313.       return 1;
  1314.   }
  1315. }
  1316.